﻿using System;
using System.IO;
using System.Text;
using System.Net;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using System.Security.Cryptography;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class AccountController : Controller
    {

        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ValidateUser(model.UserName, model.Password))
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        if (Roles.GetRolesForUser(model.UserName).Length!=0 && Roles.GetRolesForUser(model.UserName)[0] == "admin")
                            return RedirectToAction("Index", "Admin");
                        else
                            return RedirectToAction("UserManage", "Manage");  //jump to the user main page
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            FormsService.SignOut();
            Session.Clear();
            return RedirectToAction("Index", "Home");
        }

        // **************************************
        // URL: /Account/Register
        // **************************************

        public ActionResult Register()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }


        //设计成用户和品牌分离，两个对象分别存储，通过userid连接
        //注册的流程：1、验证网址管理员；2、验证网站是否已收录；3、创建用户对象；4、创建品牌（网站）对象
        //当用户通过验证管理员然后注册已有的品牌网站时，改变品牌网站对象的userid为新创建的userid，并删除原用户对象

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                if ((string)Session["validated"] != "1")
                {
                    ModelState.AddModelError("", "请先验证您的网站再进行注册，谢谢");
                    return View(model);
                }
                // Attempt to register the user
                bool isexisted;
                bool result=MembershipService.ValidateBrand(model.LinkAddr,out isexisted);
                if (result==true && isexisted==false)
                {
                    model.UserName = model.BrandName;   //暂时用品牌名作为用户名
                    MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);

                    if (createStatus == MembershipCreateStatus.Success)
                    {
                        Int64 userid=MembershipService.GetUserID(model.UserName);
                        MembershipService.CreateBrand(model.BrandName, model.LinkAddr, userid);
                        FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
                        return RedirectToAction("UserManage", "Manage");
                    }
                    else
                    {
                        ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
                    }
                }
                else if (result == true && isexisted == true)  //重新验证并注册已有品牌
                {
                    MembershipService.DeleteUser(MembershipService.GetUserNameByLinkUrl(model.LinkAddr));
                    model.UserName = model.BrandName;   //暂时用品牌名作为用户名
                    MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);
                    if (createStatus == MembershipCreateStatus.Success)
                    {
                        Int64 userid = MembershipService.GetUserID(model.UserName);
                        MembershipService.ChangeBrandOwner(model.LinkAddr,userid,model.BrandName);
                        FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
                        return RedirectToAction("UserManage", "Manage");
                    }
                    else
                    {
                        ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
                    }
                }
                else
                {
                    ModelState.AddModelError("", "该品牌当前还没有被本站收录，请与本站管理员联系");
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        //**************************************
        //execute siteverify   return 1 is success,0 is false
        //***************************************
        [HttpPost]
        public string SiteVerify(string linkaddr)
        {
            try
            {
                WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                string hashstring = client.DownloadString("http://"+linkaddr + "/siteverify.txt");
                if (hashstring == (string)Session["hashstring"])
                {
                    Session["validated"] ="1";
                    return "1";
                }
                else
                    return "0";
            }
            catch 
            {
                return "0";
            }
        }

        //**************************************
        //download the file to verify site
        //***************************************
        public FileResult DownloadVerifyFile()
        {
            try
            {
                string path = System.Web.HttpContext.Current.Server.MapPath("/Models/_siteverify.txt");
                //string path = System.Web.HttpContext.Current.Server.MapPath("/Models/_siteverify.txt"); 
                // Delete the file if it exists.
                if (System.IO.File.Exists(path))
                {
                    System.IO.File.Delete(path);
                }

                // Create the file.
                using (FileStream fs = System.IO.File.Create(path, 512))
                {
                    RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
                    byte[] randomNumber=new byte[128];
                    rngCsp.GetBytes(randomNumber);
                    MD5 md5Hasher = MD5.Create();

                    // Convert the input string to a byte array and compute the hash.
                    byte[] hashdata = md5Hasher.ComputeHash(randomNumber);

                    // Create a new Stringbuilder to collect the bytes
                    // and create a string.
                    StringBuilder sBuilder = new StringBuilder();

                    // Loop through each byte of the hashed data 
                    // and format each one as a hexadecimal string.
                    for (int i = 0; i < hashdata.Length; i++)
                    {
                        sBuilder.Append(hashdata[i].ToString("x2"));
                    }
                    Session.Timeout = 30;
                    Session["hashstring"] = sBuilder.ToString();
                    Byte[] hashstring = new UTF8Encoding(true).GetBytes(sBuilder.ToString());
                    fs.Write(hashstring, 0, hashstring.Length);
                    return File(path, "text/plain","siteverify.txt");
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [Authorize]
        public ActionResult ChangePassword()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePasswordSuccess
        // **************************************

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        public ActionResult AccountEdit(string username)
        {
            UserAccount ua = new UserAccount(username);
            MvcApplication1.Models.User currentuser=null;
            foreach (MvcApplication1.Models.User user in ua.Users)
                currentuser = user;
            return View(currentuser);
        }

        [HttpPost]
        public ActionResult AccountEdit(string email,string username)
        {
            UserAccount ua = new UserAccount(username);
            MvcApplication1.Models.User currentuser = null;
            foreach (MvcApplication1.Models.User user in ua.Users)
                currentuser = user;
            currentuser.email = email;
            ua.SaveChange();
            ViewBag.changesuccess = true;
            return View(currentuser);
        }
    }
}
